Repository navigation
Conversation
Add a Graph tab beside the Claims tab in the gene page's BioNym section. It
draws the gene's BioNym graph with bionym-components: a bar chart of the
whole graph's nodes by type (a bar click hides or shows a type), the network
in a columns or force layout, switches for kinds of edge, and a panel with a
clicked node's edges. The tabs share one minimum confidence.
The API serves the graph at /api/v1/genes/{gene_uid}/bionym/graph, from the
graphs checked into the repo. The tab's code loads only when it is first
opened, and the panel then stays on the page, hidden, so a tab switch keeps
its filters, layout and selection. Tab changes go through the History API so
a quick second click isn't lost.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FsksmWc58SyK9E2LDM4KUU
Co-authored-by: cc-claude-tools <cc-claude-tools@clevercanary.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Tab selection drops Next Pages Router history metadata, so navigating away and pressing Back can restore the gene URL while leaving the other page rendered.
1 open issue
What changed in this PR
Extends the gene page’s BioNym evidence section from a claims list to an interactive graph explorer, implementing the next stage of #1943.
Changes:
- Adds a full-graph API with node-reference validation and HTTPS-only source links.
- Introduces Claims and Graph tabs with shared confidence filtering, restoring confidence scores on claims.
- Adds a lazy-loaded graph explorer with filters, layouts, zoom controls, node details, types, and tests.
| File | Description |
|---|---|
tests/views/geneDetailView.test.tsx |
Tests tabs, confidence scores, and graph persistence. |
tests/views/bionymGraphPanel.test.tsx |
Tests graph controls, filtering, details, and links. |
tests/hooks/useGeneBionymGraph.test.tsx |
Tests graph fetching and loading states. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/utils.ts |
Adds confidence formatting and tab-hash helpers. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/types.ts |
Defines tabs and shared confidence props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/constants.ts |
Defines Claims and Graph tabs. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/utils.ts |
Adds graph filtering, counting, and link validation. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/types.ts |
Defines explorer and graph-detail types. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/hooks/useSettledValue.ts |
Debounces confidence-driven redraws. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/graphPanel.tsx |
Coordinates graph loading, filters, and selection. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/graphPanel.styles.ts |
Styles the responsive explorer and controls. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/constants.ts |
Defines hidden-edge defaults and debounce timing. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/OverviewView/types.ts |
Defines overview props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/OverviewView/overviewView.tsx |
Wraps BioNym’s node-type chart. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/NodeDetail/types.ts |
Defines node-detail props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/NodeDetail/nodeDetail.tsx |
Displays selected-node edges, confidence, and source. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/NetworkView/types.ts |
Defines network props and selection callbacks. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/NetworkView/networkView.tsx |
Wraps the network with layout and zoom controls. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/EdgeKindSwitches/types.ts |
Defines edge-filter props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphPanel/components/EdgeKindSwitches/edgeKindSwitches.tsx |
Adds edge-kind switches with counts. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphLoading/types.ts |
Defines loading-error props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/GraphLoading/graphLoading.tsx |
Displays graph loading and failure messages. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/ConfidenceControl/types.ts |
Defines shared slider props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/ConfidenceControl/confidenceControl.tsx |
Extracts the reusable confidence slider. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/ClaimsPanel/types.ts |
Defines extracted claims-panel props. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/components/ClaimsPanel/claimsPanel.tsx |
Moves claims into a panel and restores scores. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/bionymSection.tsx |
Adds tabs and persistent, lazy-loaded graph content. |
sites/brc-analytics/views/GeneDetailView/components/BionymSection/bionymSection.styles.ts |
Renames the slider’s styled container. |
sites/brc-analytics/tsconfig.json |
Includes BioNym component declarations. |
packages/shared/services/genes/types.ts |
Defines the graph API response types. |
packages/shared/services/genes/api.ts |
Adds graph fetching with missing-graph handling. |
packages/shared/services/api-client/api-client.ts |
Adds the graph endpoint client method. |
packages/shared/hooks/useGeneBionymGraph.ts |
Adds cached graph loading through React Query. |
package.json |
Adds bionym-components 0.1.1. |
package-lock.json |
Locks the BioNym dependency. |
backend/api/tests/test_genes_api.py |
Tests graph responses, validation, and safe links. |
backend/api/app/services/bionym_graphs.py |
Builds and caches validated graph views. |
backend/api/app/models/genes.py |
Adds graph response models. |
backend/api/app/api/v1/genes.py |
Exposes the full-graph endpoint. |
@types/bionym-components.d.ts |
Types the BioNym interfaces used by the explorer. |
Review effort: Balanced
…nders the gene page Choosing a tab pushed a history entry with no state, so after leaving the gene page from a tab, Back restored the gene URL but left the other page rendered. Tabs now navigate with Next's router, and the section shows the tab clicked until the last navigation is done, so a quick second click isn't lost. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsksmWc58SyK9E2LDM4KUU Co-authored-by: cc-claude-tools <cc-claude-tools@clevercanary.com>
…ng nodes, check zoom factors - `filterGraph` and `nodeEdges` throw when an edge ends at an id that isn't a node, rather than defaulting; `NodeEdge.other` is no longer optional. - The zoom test asserts the factors each button passes; `ZOOM_STEP` moves to the explorer's constants. - `toggled` moves to the explorer's `utils.ts`. - `build_graph`'s docstring names the `ValueError` it raises. - The tab hook's docstring and the router mock's comment say how Next writes a hash-only navigation; the node panel's docstring says why it has no close button. - Assertions that only checked the test's own hash helper are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsksmWc58SyK9E2LDM4KUU Co-authored-by: cc-claude-tools <cc-claude-tools@clevercanary.com>
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
Human browser validation is needed across all three full D3 graphs because tests mock BioNym components and the PR accepts force-layout freezes and incomplete cleanup in the pinned library.
No open issues 🎉
Review effort: Balanced
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Closes #1945
Note
Like #1944, this is early-stage: it puts BioNym's graph on the gene page with BioNym's own components so we can try it on real data. How the graph is presented is for the UX review in #1943 to design.
What changed
API:
GET /api/v1/genes/{gene_uid}/bionym/graph(app/services/bionym_graphs.py) returns every node and edge in the gene's checked-in BioNym graph, ortholog-group members included:https:;A gene with no graph gets a 404. The graph is built when the graphs load. A graph with an edge that ends at a node it doesn't have fails the load and the backend tests, so it never reaches the page.
Gene page, Claims and Graph tabs: the "Evidence gathered by BioNym" section now has two tabs, chosen by the URL hash (
#claims,#graph).bionym-components0.1.1 and D3, loads only when the tab is first opened.The graph explorer (
BionymSection/components/GraphPanel/):https:link to its source, and its edges, each with its confidence. It closes when you click empty space or another node.Types:
@types/bionym-components.d.tstypes the parts ofbionym-componentsthe explorer uses, since the package ships none.Why
#1944 put BioNym's claims on the gene page as a list. The rest of a BioNym graph doesn't fit a list: how the gene connects to its orthologs, assemblies, datasets, papers and conditions. This is work item 2 of "Gene pages: show the evidence BioNym gathers about a gene" (#1943).
Assumptions I made
Kinds of edge hidden by default. Four kinds start hidden:
has_member,same_as,has_candidate_geneandannotated_in. They were chosen on the three checked-in graphs at the default 0.8:has_memberlinks the gene's ortholog group to every protein in it (2,460 for Kelch13);same_aslinks aliases of one entity;has_candidate_genelinks candidate genes in related assemblies;annotated_inlinks those genes to the assemblies they're annotated in.Hiding them takes Kelch13 from 5,111 nodes to 1,002, CRT from 2,386 to 1,452, and AMA1 from 1,475 to 1,061. Kelch13's gene column drops from 1,590 genes to 35. Each kind can be shown again with its switch. Hiding kinds of edge is the only way of taming the graph this PR tries. Collapsing the ortholog group into one node, or starting from the gene and expanding outwards, are left for the UX review.
The Columns layout is the default. The Force layout is offered but not the default, because of the library bugs below.
The Graph tab stays on the page once opened. Switching to Claims hides it rather than removing it. Its filters, layout and selection survive a tab switch, and the network isn't drawn again.
The count follows the network. The network redraws once the slider has rested for 150 ms, so a drag redraws it only once. The count changes together with the network, not ahead of it.
The bar chart counts the whole graph, not what the network draws, so every type keeps a bar to click. Its label says so.
Tab changes go through Next's router, and the tab clicked shows at once. Next writes the new URL hash with no
hashchangeevent, so the section sees it only when Next renders the navigation; until Next's last navigation is done, the section shows the tab clicked. A quick second tab click isn't lost, the back button moves between tabs, and Back to the gene page from a page it links to shows the gene page again.Known bugs in
bionym-components0.1.1, reported upstream and to be fixed in a library PR:No close button on the node panel. The network can drop its selection only by redrawing, which moves the nodes in the Force layout, so a close button would either leave the node highlighted or move the graph. It comes back with the library fix, which adds a way to clear the selection.
The node and edge counts use our own copy of BioNym's confidence rule (
countShowninGraphPanel/utils.ts). The library'sfilterByConfidencecan only be reached today through the library's main entry, which loads D3, and Jest can't load D3. The follow-up after the library fix switches to the library's function.Not in scope: publishing graphs to the gene data store (Gene pages: publish BioNym graphs to the gene data store and serve them through a pin #1947), and keyboard access to the network, which belongs in the library.
How to verify
The gene snapshot bucket serves only the servers, so first build a local snapshot as
catalog/docs/gene-catalog/gene-snapshot-release-design.mddescribes. Fromcatalog/py_package, with the catalog build's requirements installed:Then run the API with
GENE_SNAPSHOT_PATH=~/genes-3d7.duckdb, run the site, and open Kelch13 (PF3D7_1343700):/data/genes/detail?uid=f0adadd3-973b-5c61-9e11-7c688b4e0895&gene-pages=true.bionym-componentsor D3 files have loaded.#graph. See the bar chart, the network in the Columns layout, and "1002 nodes and 1069 of 6536 edges".has_member (2460)and see the count rise as the ortholog group's member proteins appear. Turn it off again.Definition of done, mapped to these steps:
https:sources. A test covers a node whose URL isn'thttps:. Step 5. The tests are "links no node whose URL isn't https:" intests/views/bionymGraphPanel.test.tsx, andtest_bionym_links_other_than_https_are_droppedinbackend/api/tests/test_genes_api.py.Screenshots
Attach these from
~/Downloads/brc-analytics-1945/:brc-analytics-1945-claims-tab-desktop.png: the Claims tab, each claim with its confidence.brc-analytics-1945-graph-tab-desktop.png: the Graph tab at its defaults, in the Columns layout.brc-analytics-1945-node-detail-desktop.png: a paper selected, with its edges in the panel.brc-analytics-1945-force-layout-desktop.png: the Force layout after fit, without node names (Show node names when zoomed in on the force layout, and let the page scroll past the network d-callan/bionym#5).brc-analytics-1945-graph-page-full-desktop.png: the whole gene page on the Graph tab.brc-analytics-1945-claims-tab-phone.png,brc-analytics-1945-graph-tab-phone.png,brc-analytics-1945-node-detail-phone.png: the same on a phone, with the node panel under the network.brc-analytics-1945-graph-tab-desktop.webm: the slider, a paper node, the Force layout, then Claims and back, with the Graph tab as it was left.🤖 Generated with Claude Code
https://claude.ai/code/session_01FsksmWc58SyK9E2LDM4KUU
🐦 Built with cc-claude-tools